/*
	File:		GameplayState.cpp
	Author:		Arturo Mata, dmonroe
	Date:		11/4/2012
	Copyright:	Full Sail University

	Purpose:	State to handle gameplay
*/

#include "../source/GameplayState.h"

#include <cassert>

#include "../source/IAudio.h"
#include "../source/IGraphics.h"
#include "../source/IInput.h"
#include "../source/IObjectManager.h"

#include "../source/Constants.h"
#include "../source/Color.h"
#include "../source/Resources.h"

#include "../source/EntityType.h"
#include "../source/ObjectCreators.h"

#include "../source/IGameStateMachine.h"

#include "../source/Entity.h"		// TEST
#include "../source/EntityController_Human.h"
#include "../source/Part.h"

#include "Particles\ParticleManager.h"

//******************************************************************
// SINGLETON

// Instantiate static pointer to null (no instance yet)
/*static*/ CGameplayState*	CGameplayState::s_Instance		= NULL;

// Interface singleton accessor
/*static*/ IGameState*		CGameplayState::GetInstance		( void )
{
	// Allocate singleton on first use
	if( CGameplayState::s_Instance == NULL )
		CGameplayState::s_Instance = new CGameplayState;

	// Return the singleton
	return CGameplayState::s_Instance;
}

// Interface singleton destructor
/*virtual*/ void			CGameplayState::DeleteInstance	( void )
{
	// Deallocate singleton
	delete CGameplayState::s_Instance;
	CGameplayState::s_Instance = NULL;
}
//******************************************************************



//******************************************************************
// CONSTRUCTOR
CGameplayState::CGameplayState( void )
{
	// Set all the data members to 'clean' values
	m_pAudio			= NULL;
	m_pGraphics			= NULL;
	m_pInput			= NULL;	
	m_pObjectManager	= NULL;
	m_pWorld			= NULL;
	
	m_hTexture			= HTexture();
	m_hSapperShip		= HTexture();
	m_TestShip			= CShip();
	
	ParticleManager::GetInstance()->Init();
}
//******************************************************************



//******************************************************************
// DESTRUCTOR
CGameplayState::~CGameplayState( void )
{
	ParticleManager::GetInstance()->Shutdown();
}
//******************************************************************



//******************************************************************
// ENTER
/*virtual*/ bool CGameplayState::Enter( void )
{
	// Access the wrappers
	m_pAudio			= IAudio::GetInstance();
	m_pGraphics			= IGraphics::GetInstance();
	m_pInput			= IInput::GetInstance();
	m_pObjectManager	= IObjectManager::GetInstance();
	// Load testing files
	m_hTexture = m_pGraphics->LoadTexture( GRAPHICS_PATH( "BlueSpaceDust" ) );
	m_hSapperShip = m_pGraphics->LoadTexture( GRAPHICS_PATH( "SapperShip" ) );
	m_TestShip.Set_Part(0,0,0,0,0,0,0,0,0,m_pGraphics->LoadTexture(GRAPHICS_PATH("TestShipNose")));
	m_TestShip.Set_Part(1,0,1,0,0,0,0,0,0,m_pGraphics->LoadTexture(GRAPHICS_PATH("TestShipMid")));
	m_TestShip.Set_Part(2,0,1,0,0,0,0,0,0,m_pGraphics->LoadTexture(GRAPHICS_PATH("TestShipTail")));
	assert( m_hTexture != INVALID_HANDLE && "CMainMenuState::Enter - could not load BlueSpaceDust image" != 0 );
	assert( m_hSapperShip != INVALID_HANDLE && "CMainMenuState::Enter - could not load SapperShip image" != 0 );

	if( m_hTexture == INVALID_HANDLE || m_hSapperShip == INVALID_HANDLE )
		return false;

	m_hSound = m_pAudio->LoadAudio( SOUNDS_PATH( "LaserShot" ) );

	assert( m_hSound != INVALID_HANDLE && "CMainMenuState::Enter - could not load LaserShot sound" != 0 );

	if( m_hSound == INVALID_HANDLE )
		return false;


	// Register object types with the factory
	m_pObjectManager->Initialize();
	m_pObjectManager->RegisterObject( E_ENTITY, &CreateEntity );


	// TEST
	CEntity* pEntity = (CEntity*)m_pObjectManager->CreateAndStoreObject( E_ENTITY, NULL, E_ENTITY );
	pEntity->SetImage( m_hSapperShip );
	pEntity->SetVelocityX( +32.0f );

	CEntityController_Human* pController = new CEntityController_Human;
	pEntity->SetController( pController );
	pController->Release();

	return true;
}
//******************************************************************



//******************************************************************
// EXIT
/*virtual*/ bool CGameplayState::Exit( void )
{
	// Shutdown object manager
	m_pObjectManager->RemoveAllObjects();
	m_pObjectManager->Terminate();
	m_pObjectManager = NULL;
	IObjectManager::DeleteInstance();

	// Unload assets
	m_pGraphics->UnloadTexture( m_hTexture );
	m_hTexture = HTexture();

	m_pGraphics->UnloadTexture( m_hSapperShip );
	m_hSapperShip = HTexture();

	m_pAudio->UnloadAudio( m_hSound );
	m_hSound = HAudio();

	return true;
}
//******************************************************************



//******************************************************************
// INPUT
/*virtual*/ bool CGameplayState::Input( float fElapsedTime )
{
	// Return to menu?
	if( m_pInput->ButtonPressed( IInput::E_SELECT ) == true )
		return IGameStateMachine::GetInstance()->SwitchState( IGameStateMachine::E_MAINMENU );

	if( m_pInput->ButtonPressed( IInput::E_START ) )
		m_pAudio->Play( m_hSound );

	if( m_pInput->ButtonPressed( IInput::E_START ) )
		ParticleManager::GetInstance()->AddEmitter(0);

	// Allow game objects to read input
	m_pObjectManager->InputAllObjects( fElapsedTime );

	return true;
}
//******************************************************************



//******************************************************************
// UPDATE
/*virtual*/ bool CGameplayState::Update( float fElapsedTime )
{
	// Allow game objects to update
	m_pObjectManager->UpdateAllObjects( fElapsedTime );

	// Check all collisions?
	m_pObjectManager->CheckAllCollisions( );

	ParticleManager::GetInstance()->Update(fElapsedTime);

	return true;
}
//******************************************************************



//******************************************************************
// RENDER
/*virtual*/ bool CGameplayState::Render( float fElapsedTime )
{	
	// draw stuff
	m_pGraphics->DrawTexture( m_hTexture, 0, 0 );
	m_pGraphics->DrawTexture( m_TestShip.Get_Part(0).Get_Image_Piece() , 564, 412,0,0,0,SColor(),0.19f,0.2f );
	m_pGraphics->DrawTexture( m_TestShip.Get_Part(1).Get_Image_Piece() , 562, 514,0,0,0,SColor(),0.2f,0.2f );
	m_pGraphics->DrawTexture( m_TestShip.Get_Part(2).Get_Image_Piece() , 562, 616,0,0,0,SColor(),0.2f,0.2f );
	// Allow game objects to render
	m_pObjectManager->RenderAllObjects( fElapsedTime );

	SRect rect1 = { 100, 150, 200, 250 };
	SRect rect2 = { 175, 220, 300, 300 };
	SRect rect3;

	m_pGraphics->DrawRectangle( &rect1, 0.0f, 0.0f, 0.0f, SColor( 255, 0, 0 ) );
	m_pGraphics->DrawRectangle( &rect2, 0.0f, 0.0f, 0.0f, SColor( 0, 0, 255 ) );

	if( IntersectRect( rect1, rect2, rect3 ) == true )
		m_pGraphics->DrawRectangle( &rect3, 0.0f, 0.0f, 0.0f, SColor( 255, 255, 255 ) );

	ParticleManager::GetInstance()->Render();
	
	return true;
}
//******************************************************************
